import type { SimpleUserInfo, UserRole } from "../auth/auth";
import { fromError, initAxios, type ApiResponse } from "../common";

const client = initAxios();

export type CreateNovelFormData = {
  title: string;
  description: string;
};


export type ChapterInfoBase = {
  id: number;
  title: string;
  updated_at: string;
  visibility: boolean;
};

export type NovelInfo = {
  id: number;
  title: string;
  author: SimpleUserInfo;
  tags: string[];
  cover: string | null;
  created_at: string;
  updated_at: string;
  description: string;
  chapters: ChapterInfoBase[];
  is_favorite: boolean;
}

export async function createNovel(novel: CreateNovelFormData) {
  try {
    const resp = await client.post<ApiResponse<NovelInfo>>('/api/novel/create', novel);
    return resp.data;
  } catch (error) {
    return fromError(error);
  }
}

export async function getNovelById(id: number) {
  try {
    const resp = await client.get<ApiResponse<NovelInfo>>('/api/novel/' + id);
    return resp.data;
  } catch (error) {
    return fromError(error);
  }
}

export async function updateNovelTags(id: number, tags: string[]) {
  try {
    const resp = await client.put<ApiResponse<NovelInfo>>('/api/novel/' + id + '/tags', { tags });
    return resp.data;
  } catch (error) {
    return fromError(error);
  }
}

export async function updateNovelDescription(id: number, description: string) {
  try {
    const resp = await client.put<ApiResponse<NovelInfo>>('/api/novel/' + id + '/description', { description });
    return resp.data;
  } catch (error) {
    return fromError(error);
  }
}


export async function updateNovelTitle(id: number, title: string) {
  try {
    const resp = await client.put<ApiResponse<NovelInfo>>('/api/novel/' + id + '/title', { title });
    return resp.data;
  } catch (error) {
    return fromError(error);
  }
}

export async function updateNovelCover(id: number, cover: File) {
  try {
    const resp = await client.put<ApiResponse<NovelInfo>>('/api/novel/' + id + '/cover', cover);
    return resp.data;
  } catch (error) {
    return fromError(error);
  }
}

export type CreateChapterFormData = {
  title: string;
};

export async function createChapter(novelId: number, chapter: CreateChapterFormData) {
  try {
    const resp = await client.post<ApiResponse<ChapterInfoBase>>('/api/novel/' + novelId + '/chapter/create', chapter);
    return resp.data;
  } catch (error) {
    return fromError(error);
  }
}

export type ChapterSiblingInfo = {
  id: number;
  title: string;
};

export type ChapterInfo = {
  id: number;
  title: string;
  content: string;
  created_at: string;
  updated_at: string;
  visibility: boolean;
  draft: {
    title: string | null;
    content: string | null;
  };
  prev: ChapterSiblingInfo | null;
  next: ChapterSiblingInfo | null;
  novel: {
    id: number;
    title: string;
    author: {
      id: number;
      name: string;
      avatar: string | null;
      role: UserRole;
    };
    cover: string | null;
    created_at: string;
    updated_at: string;
  };
};

export async function getNovelChapter(novelId: number, chapterId: number) {
  try {
    const resp = await client.get<ApiResponse<ChapterInfo>>('/api/novel/' + novelId + '/chapter/' + chapterId);
    return resp.data;
  } catch (error) {
    return fromError(error);
  }
}

export async function setNovelChapterVisibility(novelId: number, chapterId: number, visibility: boolean) {
  try {
    const resp = await client.put<ApiResponse<ChapterInfo>>('/api/novel/' + novelId + '/chapter/' + chapterId + '/visibility', { visibility });
    return resp.data;
  } catch (error) {
    return fromError(error);
  }
}

export type ChapterData = {
  title: string;
  content: string;
};

export async function saveChapter(novelId: number, chapterId: number, data: ChapterData & { visibility: boolean }) {
  try {
    const resp = await client.put<ApiResponse<ChapterInfo>>('/api/novel/' + novelId + '/chapter/' + chapterId, data);
    return resp.data;
  } catch (error) {
    return fromError(error);
  }
}

export async function addFavorite(novelId: number) {
  try {
    const resp = await client.put<ApiResponse<void>>('/api/favorites/' + novelId);
    return resp.data;
  } catch (error) {
    return fromError(error);
  }
}

export async function removeFavorite(novelId: number) {
  try {
    const resp = await client.delete<ApiResponse<void>>('/api/favorites/' + novelId);
    return resp.data;
  } catch (error) {
    return fromError(error);
  }
}

export async function deleteNovel(novelId: number) {
  try {
    const resp = await client.delete<ApiResponse<boolean>>('/api/novel/' + novelId);
    return resp.data;
  } catch (error) {
    return fromError(error);
  }
}

